﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DnPakExplorer {

	/// <summary>
	/// 表示游戏中的各种装备属性、角色属性等的类
	/// </summary>
	public class Property {

		/// <summary>
		/// 此属性关联的其他数据对象
		/// </summary>
		public object tag;

		/// <summary>
		/// 属性id，比如要表示智力、体质、魔法攻击等属性
		/// </summary>
		public PropertyID id;

		/// <summary>
		/// 属性值
		/// </summary>
		public float value {
			get {
				if (PropertyUtil.IsPercentProperty((int)id)) {
					return (float)Math.Round(_value, 4);
					//return _value;
				} else
					return (int)_value;
				//return (float)Math.Round(_value, 4);
				//return _value;
			}
			set {
				_value = value;
			}
		}
		private float _value;

		/// <summary>
		/// 获取显示这个属性的值的字符串
		/// </summary>
		/// <returns></returns>
		public string GetValueString() {
			if (PropertyUtil.IsPercentProperty((int)id))
				//return Math.Round(Value*100, Util.GetPropertyDot((int)id)).ToString()+"%";
				return value*100+"%";
			else
				return value.ToString();
			//Math.Round(Value, Util.GetPropertyDot((int)id)).ToString();
		}

		/// <summary>
		/// 此属性的完整描述字符串
		/// </summary>
		/// <returns></returns>
		public override string ToString() {
			if (id == PropertyID.ID_EnchantHead) {
				return "[强化]";
			} else if (id == PropertyID.ID_Potencial2Head) {
				return "[附魔]";
			} else if (id == PropertyID.ID_PotencialHead) {
				return "[制作]";
			} else {
				string propText = PropertyUtil.GetPropertyName((int)id)+":"+GetValueString();
				if (tag is int)
					return tag+"套 "+propText;
				else
					return propText;
			}
		}
	}

	/// <summary>
	/// 属性id，注意枚举值不可随意修改
	/// </summary>
	public enum PropertyID : int {
		Strength			= 0,		// 力量
		Agility				= 1,		// 敏捷
		Intelligence		= 2,		// 智力
		Stamina				= 3,		// 体质

		MinPysicalAttack	= 4,		// 最小物理攻击
		MaxPysicalAttack	= 5,		// 最大物品攻击
		MinMagicAttack		= 6,		// 最小魔法攻击
		MaxMagicAttack		= 7,		// 最大魔法攻击

		PysicalDefense		= 8,		// 物理防御
		MagicDefense		= 9,		// 魔法防御

		Stiff				= 10,		// 硬直
		StiffResistance		= 11,		// 硬直抵抗
		Critical			= 12,		// 致命一击
		CriticalResistance	= 13,		// 致命一击抵抗
		Stun				= 14,		// 眩晕
		StunResistance		= 15,		// 眩晕抵抗

		MoveSpeed			= 24,		// 移动数度
		CriticalDamage		= 103,		// 致命一击伤害
		FinalDamage			= 29,		// 最终伤害
							  
		FireAttack			= 16,		// 火攻击
		WaterAttack			= 17,		// 水攻击
		LightAttack			= 18,		// 光攻击
		DarkAttack			= 19,		// 暗攻击
							  
		FireDefense			= 20,		// 火防御
		WaterDefensek		= 21,		// 水防御
		LightDefense		= 22,		// 光防御
		DarkDefense			= 23,		// 暗防御
							  
		HP					= 25,		// 生命值
		MP					= 26,		// 魔法值

		PhysicalAttack		= 32,		// 物理攻击
		MagicAttack			= 33,		// 魔法攻击

		ID_PotencialHead	= 199,
		ID_EnchantHead		= 198,
		ID_Potencial2Head	= 197,

		ID_MAX				= 200,
	}

	/// <summary>
	/// 和属性相关的工具类
	/// </summary>
	public class PropertyUtil {

		/// <summary>
		/// 属性名称集合
		/// </summary>
		private static string[] mPropertyName = new string[200] {
			/*		0		1			2			3				4				5				6				7				8			9*/
			/* 0*/ "力量",	"敏捷",		"智慧",		"体质",			"最小物理攻击",	"最大物理攻击",	"最小魔法攻击",	"最大魔法攻击",	"防御力",		"魔法防御力",
			/* 1*/ "硬直",	"硬直抵抗",	"致命一击",	"致命一击抵抗",	"眩晕",			"眩晕抵抗",		"火攻击",			"水攻击",			"光攻击",		"暗攻击",
			/* 2*/ "火防御",	"水防御",		"光防御",		"暗防御",			"移动速度",		"Max HP",		"Max MP",		"MP恢复",		"",		"最终伤害",
			
			/* 3*/ "",		"",			"物理攻击",	"魔法攻击力",		"",				"",				"",				"",				"",			"",
			/* 4*/ "",		"",			"",			"",				"",				"",				"",				"",				"",			"",
			/**************************************************************************************************************************************************/
			/* 5*/ "力量%",	"敏捷%",		"智慧%",		"体质%",			"最小物理攻击%",	"最大物理攻击%",	"最小魔法攻击%",	"最大魔法攻击%",	"防御力%",	"魔法防御力%",
			/* 6*/ "硬直%",	"硬直抵抗%", "致命一击%",	"致命一击抵抗%",	"眩晕%",			"眩晕抵抗%",		"",				"",				"",			"",
			/* 7*/ "",		"",			"",			"",				"移动速度%",		"HP%",			"MP%",			"MP恢复%",		"",			"最终%",
			/* 8*/ "",		"",			"",			"",				"",				"",				"",				"",				"",			"",
			/* 9*/ "",		"",			"",			"",				"",				"",				"",				"",				"",			"",
			
			/*10*/ "韧性",	"物理攻击%",	"魔法攻击%",	"致命一击伤害",	"致命一击伤害%",	"pvp攻击力",		"pvp防御力",		"Max MP2",		"",			"",
			/*11*/ "",		"", "", "", "", "", "", "", "", "",
			/*12*/ "",		"", "", "", "", "", "", "", "", "",
			/*13*/ "",		"", "", "", "", "", "", "", "", "",
			/*14*/ "",		"", "", "", "", "", "", "", "", "",
			/*15*/ "",		"", "", "", "", "", "", "", "", "",
			/*16*/ "",		"", "", "", "", "", "", "", "", "",
			/*17*/ "",		"", "", "", "", "", "", "", "", "",
			/*18*/ "",		"", "", "", "", "", "", "", "", "",
			/*19*/ "",		"", "", "", "", "", "", "", "", "",
		};

		/// <summary>
		/// 属性值的小数位数
		/// </summary>
		private static sbyte[] mPropertyDot = new sbyte[]{
			/*     0, 1, 2, 3, 4, 5, 6, 7, 8, 9		*/
			/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*01*/ 0, 0, 0, 0, 0, 0, 2, 2, 2, 2,
			/*02*/ 2, 2, 2, 2, 0, 0, 0, 0, 0, 0,
			/*03*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*04*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*05*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
			/*06*/ 2, 2, 2, 2, 2, 2, 2, 0, 0, 2,
			/*07*/ 0, 0, 0, 0, 2, 2, 2, 0, 0, 0,
			/*08*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*09*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*10*/ 0, 2, 2, 2, 0, 2, 0, 0, 0, 0,
			/*11*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*12*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*13*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*14*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*15*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*16*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*17*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*18*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			/*19*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		};

		private static int[] mGenPropertyMap = new int[200] {
			/*00*/ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
			/*01*/ 60, 61, 62, 63, 64, 65, -1, -1, -1, -1,
			/*02*/ -1, -1, -1, -1, 74, 75, 76, -1, -1, 79,
			/*03*/ -1, -1, 101, 102, -1, -1, -1, -1, -1, -1,
			/*04*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*05*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*06*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*07*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*08*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*09*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*10*/ -1, -1, -1, 104, -1, -1, -1, -1, -1, -1,
			/*11*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*12*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*13*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*14*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*15*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*16*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*17*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*18*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*19*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		};

		/// <summary>
		/// 一种属性关联两种属性的映射表，比如魔法攻击属性可以关联到最大魔法攻击属性和最小魔法攻击属性
		/// </summary>
		private static int[] mPropertyOneMapTwo = new int[200] {
			/*00*/ -1, -1, -1, -1, 1000032, 1000032, 1000033, 1000033, -1, -1,
			/*01*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*02*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*03*/ -1, -1, 4005, 6007, -1, -1, -1, -1, -1, -1,
			/*04*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*05*/ -1, -1, -1, -1, 1000101, 1000101, 1000102, 1000102, -1, -1,
			/*06*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*07*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*08*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*09*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*10*/ -1, 54055, 56057, -1, -1, -1, -1, -1, -1, -1,
			/*11*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*12*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*13*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*14*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*15*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*16*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*17*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*18*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			/*19*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		};

		public static int GetPropertyDot(int pid) {
			return mPropertyDot[pid];
		}

		/// <summary>
		/// 获取一种属性所关联的其他两种属性
		/// </summary>
		/// <param name="pid"></param>
		/// <param name="p1">返回关联属性1</param>
		/// <param name="p2">返回关联属性1</param>
		/// <returns>如果属性pid没有关联其他属性则返回-1</returns>
		public static int GetPropertyOneMapTwo(int pid, out int p1, out int p2) {
			int value = mPropertyOneMapTwo[pid];
			if (value>=1000000) {
				p1 = p2 = -1;
				return value-1000000;
			} else if (value != -1) {
				p1 = value / 1000;
				p2 = value % 1000;
				return -1;
			}
			p1 = p2 = -1;
			return -1;
		}

		/// <summary>
		/// 获取一种属性对应的百分比加成属性
		/// </summary>
		/// <returns>如果没有对象百分比加成属性，则返回-1</returns>
		public static int GetGenProperty(int pid) {
			return mGenPropertyMap[pid];
		}

		/// <summary>
		/// 判断属性是否在游戏已经应用
		/// </summary>
		public static bool IsAppliedProperty(int pid) {
			return mPropertyName[pid] != "";
		}

		/// <summary>
		/// 判断属性是否是百分比加成属性
		/// </summary>
		/// <param name="pid"></param>
		/// <returns></returns>
		public static bool IsGenProperty(int pid) {
			for (int i=0; i<mGenPropertyMap.Length; i++)
				if (mGenPropertyMap[i] == pid)
					return true;
			return false;
		}

		/// <summary>
		/// 判断属性是否是百分比加成属性
		/// </summary>
		/// <param name="pid"></param>
		/// <returns></returns>
		public static bool IsPercentProperty(int pid) {
			pid = (pid)%1000;
			return pid>=0 && pid < 190 && (pid>=16 && pid<=23 || mPropertyName[pid].EndsWith("%"));
		}

		/// <summary>
		/// 判断属性是否是元素（火、水、光、暗）属性
		/// </summary>
		/// <param name="pid"></param>
		/// <returns></returns>
		public static bool IsElementProperty(int pid) {
			return pid>=(int)PropertyID.FireAttack && pid<=(int)PropertyID.DarkDefense;
		}

		/// <summary>
		/// 获取属性名称
		/// </summary>
		public static string GetPropertyName(int id) {
			if (id>=0 && id<mPropertyName.Length) {
				string name = mPropertyName[id];
				if (name == "")
					return id.ToString();
				if (name.EndsWith("%"))
					name = name.Substring(0, name.Length-1);
				return name;
			}
			return id.ToString();
		}
	}
}
